static void net_rx_action(unsigned long unused);
static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0);
-typedef struct {
- u16 id;
- unsigned long old_mach_ptr;
- unsigned long new_mach_pfn;
- netif_t *netif;
-} rx_info_t;
static struct sk_buff_head rx_queue;
static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2];
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE*3];
#define PKT_PROT_LEN (ETH_HLEN + 20)
-static u16 pending_id[MAX_PENDING_REQS];
-static netif_t *pending_netif[MAX_PENDING_REQS];
+static struct {
+ netif_tx_request_t req;
+ netif_t *netif;
+} pending_tx_info[MAX_PENDING_REQS];
static u16 pending_ring[MAX_PENDING_REQS];
typedef unsigned int PEND_RING_IDX;
#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED;
static PEND_RING_IDX dealloc_prod, dealloc_cons;
-typedef struct {
- u16 idx;
- netif_tx_request_t req;
- netif_t *netif;
-} tx_info_t;
static struct sk_buff_head tx_queue;
static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
{
netif_t *netif = (netif_t *)dev->priv;
+ ASSERT(skb->dev == dev);
+
/* Drop the packet if the target domain has no receive buffers. */
if ( (netif->rx_req_cons == netif->rx->req_prod) ||
((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
skb_reserve(nskb, hlen);
__skb_put(nskb, skb->len);
(void)skb_copy_bits(skb, -hlen, nskb->head, hlen + skb->len);
+ nskb->dev = skb->dev;
dev_kfree_skb(skb);
skb = nskb;
}
- ((rx_info_t *)&skb->cb[0])->id =
- netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_req_cons++)].req.id;
- ((rx_info_t *)&skb->cb[0])->netif = netif;
-
- __skb_queue_tail(&rx_queue, skb);
+ netif->rx_req_cons++;
+
+ skb_queue_tail(&rx_queue, skb);
tasklet_schedule(&net_rx_tasklet);
return 0;
netif_t *netif;
s8 status;
u16 size, id, evtchn;
- mmu_update_t *mmu = rx_mmu;
+ mmu_update_t *mmu;
multicall_entry_t *mcl;
unsigned long vdata, mdata, new_mfn;
struct sk_buff_head rxq;
skb_queue_head_init(&rxq);
mcl = rx_mcl;
- while ( (skb = __skb_dequeue(&rx_queue)) != NULL )
+ mmu = rx_mmu;
+ while ( (skb = skb_dequeue(&rx_queue)) != NULL )
{
- netif = ((rx_info_t *)&skb->cb[0])->netif;
+ netif = (netif_t *)skb->dev->priv;
vdata = (unsigned long)skb->data;
mdata = virt_to_machine(vdata);
new_mfn = get_new_mfn();
mcl[1].args[1] = 3;
mcl[1].args[2] = 0;
- mmu += 3;
mcl += 2;
+ mmu += 3;
- ((rx_info_t *)&skb->cb[0])->old_mach_ptr = mdata;
- ((rx_info_t *)&skb->cb[0])->new_mach_pfn = new_mfn;
__skb_queue_tail(&rxq, skb);
/* Filled the batch queue? */
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
mcl = rx_mcl;
+ mmu = rx_mmu;
while ( (skb = __skb_dequeue(&rxq)) != NULL )
{
- netif = ((rx_info_t *)&skb->cb[0])->netif;
+ netif = (netif_t *)skb->dev->priv;
size = skb->tail - skb->data;
- id = ((rx_info_t *)&skb->cb[0])->id;
- new_mfn = ((rx_info_t *)&skb->cb[0])->new_mach_pfn;
- mdata = ((rx_info_t *)&skb->cb[0])->old_mach_ptr;
+ /* Rederive the machine addresses. */
+ new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
+ mdata = ((mmu[2].ptr & PAGE_MASK) |
+ ((unsigned long)skb->data & ~PAGE_MASK));
+
/* Check the reassignment error code. */
if ( unlikely(mcl[1].args[5] != 0) )
{
}
evtchn = netif->evtchn;
+ id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
if ( make_rx_response(netif, id, status, mdata, size) &&
(rx_notify[evtchn] == 0) )
{
dev_kfree_skb(skb);
mcl += 2;
+ mmu += 3;
}
while ( notify_nr != 0 )
{
pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
- netif = pending_netif[pending_idx];
+ netif = pending_tx_info[pending_idx].netif;
spin_lock(&netif->tx_lock);
- make_tx_response(netif, pending_id[pending_idx], NETIF_RSP_OKAY);
+ make_tx_response(netif, pending_tx_info[pending_idx].req.id,
+ NETIF_RSP_OKAY);
spin_unlock(&netif->tx_lock);
pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
mcl[0].args[2] = 0;
mcl[0].args[3] = netif->domid;
mcl++;
-
- ((tx_info_t *)&skb->cb[0])->idx = pending_idx;
- ((tx_info_t *)&skb->cb[0])->netif = netif;
- memcpy(&((tx_info_t *)&skb->cb[0])->req, &txreq, sizeof(txreq));
+
+ memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
+ pending_tx_info[pending_idx].netif = netif;
+ *((u16 *)skb->data) = pending_idx;
+
__skb_queue_tail(&tx_queue, skb);
pending_cons++;
mcl = tx_mcl;
while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
{
- pending_idx = ((tx_info_t *)&skb->cb[0])->idx;
- netif = ((tx_info_t *)&skb->cb[0])->netif;
- memcpy(&txreq, &((tx_info_t *)&skb->cb[0])->req, sizeof(txreq));
+ pending_idx = *((u16 *)skb->data);
+ netif = pending_tx_info[pending_idx].netif;
+ memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
/* Check the remap error code. */
if ( unlikely(mcl[0].args[5] != 0) )
*/
page->mapping = (struct address_space *)netif_page_release;
atomic_set(&page->count, 1);
- pending_id[pending_idx] = txreq.id;
- pending_netif[pending_idx] = netif;
netif->stats.tx_bytes += txreq.size;
netif->stats.tx_packets++;
return NULL;
}
-#define MULTIVIF
-
/** Network interface info. */
struct netif_ctrl {
/** Number of interfaces. */
unsigned long flags;
spin_lock_irqsave(&np->tx_lock, flags);
-
- if( !netif_carrier_ok(dev) )
- {
- spin_unlock_irqrestore(&np->tx_lock, flags);
- return;
- }
-
- network_tx_buf_gc(dev);
+ if ( likely(netif_carrier_ok(dev)) )
+ network_tx_buf_gc(dev);
spin_unlock_irqrestore(&np->tx_lock, flags);
if ( np->rx_resp_cons != np->rx->resp_prod )
spin_lock(&np->rx_lock);
- /* if the device is undergoing recovery then don't do anything */
+ /* If the device is undergoing recovery then don't do anything. */
if ( !netif_carrier_ok(dev) )
{
spin_unlock(&np->rx_lock);
memcpy(dev->dev_addr, status->mac, ETH_ALEN);
- if(netif_carrier_ok(dev)){
+ if ( netif_carrier_ok(dev) )
np->state = NETIF_STATE_CONNECTED;
- } else {
+ else
network_reconnect(dev, status);
- }
np->evtchn = status->evtchn;
np->irq = bind_evtchn_to_irq(np->evtchn);
(void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM,
dev->name, dev);
-#ifdef MULTIVIF
netctrl_connected_count();
-#endif
break;
default:
}
}
-/** Create a network devices.
- *
+/** Create a network device.
* @param handle device handle
* @param val return parameter for created device
* @return 0 on success, error code otherwise
*/
-static int create_netdev(int handle, struct net_device **val){
+static int create_netdev(int handle, struct net_device **val)
+{
int err = 0;
struct net_device *dev = NULL;
struct net_private *np = NULL;
{
ctrl_msg_t cmsg;
netif_fe_driver_status_changed_t st;
- int err = 0;
-#ifdef MULTIVIF
- int wait_n = 20;
- int wait_i;
-#endif
+ int err = 0, wait_i, wait_n = 20;
if ( (start_info.flags & SIF_INITDOMAIN) ||
(start_info.flags & SIF_NET_BE_DOMAIN) )
printk("Initialising Xen virtual ethernet frontend driver");
INIT_LIST_HEAD(&dev_list);
-#ifdef MULTIVIF
+
netctrl_init();
-#endif
(void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
CALLBACK_IN_BLOCKING_CONTEXT);
memcpy(cmsg.msg, &st, sizeof(st));
ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-#ifdef MULTIVIF
/* Wait for all interfaces to be connected. */
for ( wait_i = 0; ; wait_i++)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
-#endif
if ( err )
ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);